#include "DotFileWriter.h"
#include <format>
#include <functional>
#include <algorithm>
#include "FileReader.h"



using namespace DotFileWriter;

/**
 * @brief 构造函数，初始化DOT文件路径
 * @param filePath DOT文件的完整路径
 */
DotFile::DotFile(const std::string& filePath) : m_filePath(filePath)
{}


/**
 * @brief 析构函数，关闭文件流（如果已打开）
 */
DotFile::~DotFile(){
    close(); // 确保文件流被关闭
}


/**
 * @brief 打开文件流准备写入DOT内容
 * @return 成功打开返回true，文件不存在或无法打开返回false
 */
bool DotFile::open(){
    // 以写入模式打开文件，若文件不存在则创建
    m_outFile.open(m_filePath);
    if (!m_outFile.is_open()) {
        std::cerr << "Failed to open the file: " << m_filePath << std::endl;
        return false;
    }
    
    return true;
}

bool DotFile::loadFile(const std::string& filePath){
    // Load the file from the given path
    m_filePath = filePath;
    return open();
}

void DotFile::close(){
    m_outFile.close();
}


/**
 * @brief 写入DOT文件头部定义
 * @note 设置图形方向为自底向上(BT)，节点字体为微软雅黑以支持中文显示
 */
void DotFile::writeHeader() {
    m_outFile << std::format("digraph {{\n");
    m_outFile << std::format("\trankdir=BT\n");
    m_outFile << std::format("\tranksep = 3.0\n");
    m_outFile << "\t" << R"(node [charset="UTF-8", fontname="Microsoft YaHei"])" << std::endl; // 显式声明编码
}


void DotFile::writeSubgraph(const std::string& name, const std::string& silLvl, const std::string& clusterName){
    std::function<std::string(const std::string&)> tempToUpper = [](const std::string& str) {
        std::string result = str;
        std::transform(result.begin(), result.end(), result.begin(),
            [](unsigned char c) { return std::toupper(c); });
        return result;
    };

    m_outFile << std::format("\tsubgraph cluster_{} {{\n",clusterName);
    silLvl.empty()? (m_outFile << std::format("\t\tlabeljust = \"l\" \n")) : (m_outFile << std::format("\t\tlabeljust = \"l\" \n"), m_outFile << std::format("\t\tlabel = \"{}\" \n",silLvl));
    
    
    std::string upperSILLVL = tempToUpper(silLvl);

    if ( sil_4_vector.end() != std::find(sil_4_vector.begin(), sil_4_vector.end(), upperSILLVL)) {
        m_outFile << std::format("\t\tbgcolor = orangered\n");
    } else if (sil_2_vector.end() != std::find(sil_2_vector.begin(), sil_2_vector.end(), upperSILLVL)) {
        m_outFile << std::format("\t\tbgcolor = yellow\n");
    } else if (sil_0_vector.end() != std::find(sil_0_vector.begin(), sil_0_vector.end(), upperSILLVL)) {
        m_outFile << std::format("\t\tbgcolor = green\n");
    }
    m_outFile << std::format("\t\t\"{}\"\n", name);
    m_outFile << std::format("\t}}\n");
}


void DotFile::writeNode(const std::string& name){ 
    m_outFile << std::format("\t{}\n", name);
}


void DotFile::writeEnd(){
    m_outFile << "}";
    // close();
}